#pragma once

#include "noncopyable.h"


#include <string>


// 定义日志的级别 INFO ERROR FATAL DEBUG
enum class LogLevel : int
{
    // 普通信息
    INFO, 
    // 错误信息
    ERROR,
    // core信息
    FATAL,
    // 调试信息
    DEBUG
};

// 日志类
class Logger : noncopyable
{
public:
    // 获取唯一的日志示例对象
    static Logger& getInstance();
    // 设置日志级别
    void setLogLevel(LogLevel level);
    // 获取日志级别
    LogLevel getLogLevel() const;
    // 写日志
    void log(std::string msg);

private:
    Logger() = default;

private:
    LogLevel m_logLevel;    
};

// LOG_INFO("%s %d", arg1, arg2...)
#define LOG_INFO(logmsgFormat, ...) \
                do \
                { \
                    Logger& logger = Logger::getInstance(); \
                    logger.setLogLevel(LogLevel::INFO); \
                    char buf[1024] = {0}; \
                    snprintf(buf, 1024, logmsgFormat, ##__VA_ARGS__); \
                    logger.log(buf); \
                } while(0)

#define LOG_ERROR(logmsgFormat, ...) \
    do \
    { \
        Logger &logger = Logger::getInstance(); \
        logger.setLogLevel(LogLevel::ERROR); \
        char buf[1024] = {0}; \
        snprintf(buf, 1024, logmsgFormat, ##__VA_ARGS__); \
        logger.log(buf); \
    } while(0) 

#define LOG_FATAL(logmsgFormat, ...) \
    do \
    { \
        Logger &logger = Logger::getInstance(); \
        logger.setLogLevel(LogLevel::FATAL); \
        char buf[1024] = {0}; \
        snprintf(buf, 1024, logmsgFormat, ##__VA_ARGS__); \
        logger.log(buf); \
        exit(-1); \
    } while(0)        

#ifdef MUDEBUG
#define LOG_DEBUG(logmsgFormat, ...) \
    do \
    { \
        Logger &logger = Logger::instance(); \
        logger.setLogLevel(LogLevel::DEBUG); \
        char buf[1024] = {0}; \
        snprintf(buf, 1024, logmsgFormat, ##__VA_ARGS__); \
        logger.log(buf); \
    } while(0) 
#else
    #define LOG_DEBUG(logmsgFormat, ...)
#endif         


